package com.zmn.brs.business.impl.objective;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zmn.brs.business.interfaces.objective.ObjectiveWarnBService;
import com.zmn.brs.common.model.dio.objective.ObjectiveMasterTargetDIO;
import com.zmn.brs.common.model.dio.objective.ObjectiveTargetDIO;
import com.zmn.brs.common.model.dio.objective.ObjectiveWarnDIO;
import com.zmn.brs.common.model.dio.objective.ObjectiveWarnQueryDIO;
import com.zmn.brs.drools.bean.ObjectiveMonitorData;
import com.zmn.brs.model.entity.objective.record.ObjectiveRecordQuery;
import com.zmn.brs.model.entity.task.version.TaskVersion;
import com.zmn.brs.model.query.record.ObjectiveRecordCustomDIO;
import com.zmn.brs.services.interfaces.objective.record.ObjectiveRecordService;
import com.zmn.brs.services.interfaces.record.EventRecordService;
import com.zmn.brs.services.interfaces.task.version.TaskVersionService;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.manager.common.database.annotation.ReadOnlyConnection;
import com.zmn.mcc.dubbo.interfaces.staff.StaffListRemoteService;
import com.zmn.okr.common.constant.ObjectiveMasterTypeConst;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 描述：
 *
 * @author chongw
 * @since 2021-06-22 16:51
 */
@Slf4j
@Service
public class ObjectiveWarnBServiceImpl implements ObjectiveWarnBService {

    public static final String TAG = "目标指标预警接口实现";

    @Resource
    private EventRecordService eventRecordService;

    @Reference(version = com.zmn.mcc.dubbo.dto.DubboConsts.INTERFACE_VERSION, check = false)
    private StaffListRemoteService staffListRemoteService;

    @Resource
    private ObjectiveRecordService objectiveRecordService;

    @Resource
    private TaskVersionService taskVersionService;

    /**
     * 描述: 目标监控指标查询
     * @param query
     * 目标监控指标查询
     * @return com.zmn.common.dto.ResponseDTO<java.lang.Boolean>
     * @author wangjie
     * @since 2019/8/2
     **/
    @Override
    @ReadOnlyConnection
    public ObjectiveWarnDIO getObjectiveWarnByQuery(ObjectiveWarnQueryDIO query){

        try {
            //获取计算版本
            TaskVersion taskVersion = Optional.ofNullable(taskVersionService.findByVersion(query.getTaskVersionId())).orElse(TaskVersion.builder().build());
            Date time = Optional.ofNullable(taskVersion.getMonitorStartTime()).orElse(DateUtil.getNow());
            //获取数据展示层级
            Integer dataLevel = this.getDataLevel(query.getObjMasterId(), query.getTaskVersionId());
            //获取责任数据
            List<ObjectiveMasterTargetDIO> masterTargetDIOList = this.getObjectiveMasterTargetDIOByRecord(
                    ObjectiveRecordQuery.builder()
                            .objMasterId(query.getObjMasterId())
                            .monitorVersion(query.getTaskVersionId())
                            .build(), dataLevel
            );

            ObjectiveWarnDIO objectiveWarnDIO = ObjectiveWarnDIO.builder()
                    .staffId(query.getObjMasterId())
                    .month(DateUtil.dateFormatToString(time, DateUtil.FORMAT_MONTH))
                    .endTime(DateUtil.dateFormatToString(time, DateUtil.FORMAT_DATE))
                    .objectiveMasters(masterTargetDIOList)
                    .subObjectiveMasters(this.getSubObjectiveMasters(query , dataLevel))
                    .build();
            return objectiveWarnDIO;
        }catch (Exception e){
            e.printStackTrace();
            log.error("[{}], 接口入参：{}, 异常信息：{}" , TAG , JSONObject.toJSONString(query) , e);
        }
        return ObjectiveWarnDIO.builder()
                .staffId(query.getObjMasterId())
                .month(DateUtil.dateFormatToString(DateUtil.getNow(), DateUtil.FORMAT_MONTH))
                .endTime(DateUtil.dateFormatToString(DateUtil.getNow(), DateUtil.FORMAT_DATE))
                .build();
    }

    /**
     * 获取下级数据
     * @param query
     * @return
     */
    protected List<ObjectiveMasterTargetDIO> getSubObjectiveMasters(ObjectiveWarnQueryDIO query, Integer dataLevel){
        //负责人上级部门
        if(ObjectiveMasterTypeConst.MASTERTYPE_DEFAULT.equals(dataLevel)){
            //有子部门的情况
            List<ObjectiveRecordCustomDIO> deptYList = Optional.ofNullable(objectiveRecordService.listObjectiveRecordByQuery(ObjectiveRecordQuery.builder()
                    .parentDeptManagerId(query.getObjMasterId())
                    .isParent(0)
                    .level(3)
                    .monitorVersion(query.getTaskVersionId())
                    .build())).orElse(new ArrayList<>());

            List<ObjectiveMasterTargetDIO> list = Optional.ofNullable(deptYList.stream().map(o -> {
                return Arrays.asList(Optional.ofNullable(o.getDeptManagerId()).orElse(-1) ,
                        Optional.ofNullable(o.getDeptId()).orElse(-1),
                        o.getDeptName());
            }).filter(o -> {
                return Integer.parseInt(String.valueOf(o.get(1))) != -1;
            }).distinct().map(o -> {
                Integer deptId = Integer.parseInt(String.valueOf(o.get(1)));
                String deptName = String.valueOf(o.get(2));
                Integer objMasterId = Integer.parseInt(String.valueOf(o.get(0)));
                ObjectiveMasterTargetDIO deptDIO = Optional.ofNullable(this.getObjectiveMasterTargetDIOByRecord(ObjectiveRecordQuery.builder()
                        .objMasterId(objMasterId)
                        .monitorVersion(query.getTaskVersionId())
                        .isDept(true)
                        .level(3)
                        .build())).orElse(ObjectiveMasterTargetDIO.builder().build());
                deptDIO.setObjMasterId(deptId);
                deptDIO.setObjMasterName(deptName);
                deptDIO.setObjMasterType(ObjectiveMasterTypeConst.MASTERTYPE_DEPT);
                deptDIO.setSubObjectiveMasters(this.getDeptSubObjectiveMasters(ObjectiveRecordQuery.builder()
                        .deptId(deptId)
                        .isDept(false)
                        .monitorVersion(query.getTaskVersionId())
                        .level(3)
                        .build()));
                return deptDIO;
            }).collect(Collectors.toList())).orElse(new ArrayList<>());

            //无子部门的情况
            List<ObjectiveRecordCustomDIO> deptNList = Optional.ofNullable(objectiveRecordService.listObjectiveRecordByQuery(ObjectiveRecordQuery.builder()
                    .parentDeptManagerId(-1)
                    .level(3)
                    .deptManagerId(query.getObjMasterId())
                    .monitorVersion(query.getTaskVersionId())
                    .build())).orElse(new ArrayList<>());
            list.addAll(deptNList.stream().map(o -> {
                return Arrays.asList(Optional.ofNullable(o.getDeptManagerId()).orElse(-1) ,
                        Optional.ofNullable(o.getObjMasterId()).orElse(-1));
            }).distinct().map(o -> {
                Integer deptManagerId = Integer.parseInt(String.valueOf(o.get(0)));
                Integer objMasterId = Integer.parseInt(String.valueOf(o.get(1)));
                return this.getObjectiveMasterTargetDIOByRecord(ObjectiveRecordQuery.builder()
                        .objMasterId(objMasterId)
                        .deptManagerId(deptManagerId)
                        .level(3)
                        .monitorVersion(query.getTaskVersionId())
                        .build());
            }).collect(Collectors.toList()));
            return list;
        }
        //负责人当前部门下所有责任人
        if(ObjectiveMasterTypeConst.MASTERTYPE_DEPT.equals(dataLevel)){
            return this.getDeptSubObjectiveMasters(ObjectiveRecordQuery.builder()
                    .deptManagerId(query.getObjMasterId())
                    .monitorVersion(query.getTaskVersionId())
                    .isDept(false)
                    .level(2)
                    .build());
        }
        return new ArrayList<>();
    }

    /**
     * 获取直接部门数据
     * @param query
     * @return
     */
    protected List<ObjectiveMasterTargetDIO> getDeptSubObjectiveMasters(ObjectiveRecordQuery query){
        List<ObjectiveRecordCustomDIO> list = Optional.ofNullable(objectiveRecordService.listObjectiveRecordByQuery(query)).orElse(new ArrayList<>());
        if(list.size() <= 0){
            return null;
        }
        return list.stream().map(o -> {
            return o.getObjMasterId();
        }).distinct().map(o -> {
            return this.getObjectiveMasterTargetDIOByRecord(ObjectiveRecordQuery.builder()
                    .objMasterId(o)
                    .deptId(query.getDeptId())
                    .deptManagerId(query.getDeptManagerId())
                    .monitorVersion(query.getMonitorVersion())
                    .build());
        }).collect(Collectors.toList());
    }

    /**
     * 获取责任人指标数据
     * @param query
     * @param dataLevel
     * @return
     */
    protected List<ObjectiveMasterTargetDIO> getObjectiveMasterTargetDIOByRecord(ObjectiveRecordQuery query, Integer dataLevel){
        //负责人上级部门
        if(ObjectiveMasterTypeConst.MASTERTYPE_DEFAULT.equals(dataLevel)){
            List<ObjectiveRecordCustomDIO> list = Optional.ofNullable(objectiveRecordService.listObjectiveRecordByQuery(ObjectiveRecordQuery.builder()
                    .parentDeptManagerId(query.getObjMasterId())
                    .monitorVersion(query.getMonitorVersion())
                    .build())).orElse(new ArrayList<>());
            return list.stream().map(o -> {
                return Arrays.asList(Optional.ofNullable(Optional.ofNullable(o.getParentDeptManagerId()).orElse(o.getDeptManagerId())).orElse(-1) ,
                        Optional.ofNullable(Optional.ofNullable(o.getParentDeptId()).orElse(o.getDeptId())).orElse(-1) ,
                        Optional.ofNullable(o.getParentDeptName()).orElse(o.getDeptName()));
            }).filter(o -> {
                return Integer.parseInt(String.valueOf(o.get(1))) != -1;
            }).distinct().map(o -> {
                Integer deptId = Integer.parseInt(String.valueOf(o.get(1)));
                String deptName = String.valueOf(o.get(2));
                Integer objMasterId = Integer.parseInt(String.valueOf(o.get(0)));
                ObjectiveMasterTargetDIO deptDIO = Optional.ofNullable(this.getObjectiveMasterTargetDIOByRecord(ObjectiveRecordQuery.builder()
                        .objMasterId(objMasterId)
                        .parentDeptId(deptId)
                        .monitorVersion(query.getMonitorVersion())
                        .build())).orElse(ObjectiveMasterTargetDIO.builder().build());
                deptDIO.setObjMasterId(deptId);
                deptDIO.setObjMasterName(deptName);
                deptDIO.setObjMasterType(ObjectiveMasterTypeConst.MASTERTYPE_DEFAULT);
                return deptDIO;
            }).collect(Collectors.toList());
        }
        //负责人当前部门下所有责任人
        if(ObjectiveMasterTypeConst.MASTERTYPE_DEPT.equals(dataLevel)){
            List<ObjectiveRecordCustomDIO> list = Optional.ofNullable(objectiveRecordService.listObjectiveRecordByQuery(ObjectiveRecordQuery.builder()
                    .deptManagerId(query.getObjMasterId())
                    .monitorVersion(query.getMonitorVersion())
                    .build())).orElse(new ArrayList<>());
            return list.stream().map(o -> {
                return Arrays.asList(Optional.ofNullable(o.getDeptManagerId()).orElse(-1),
                        Optional.ofNullable(o.getDeptId()).orElse(-1), o.getDeptName());
            }).filter(o -> {
                return Integer.parseInt(String.valueOf(o.get(1))) != -1;
            }).distinct().map(o -> {
                Integer deptId = Integer.parseInt(String.valueOf(o.get(1)));
                String deptName = String.valueOf(o.get(2));
                Integer objMasterId = Integer.parseInt(String.valueOf(o.get(0)));

                ObjectiveMasterTargetDIO deptDIO = Optional.ofNullable(this.getObjectiveMasterTargetDIOByRecord(ObjectiveRecordQuery.builder()
                        .objMasterId(objMasterId)
                        .deptId(deptId)
                        .isDept(true)
                        .monitorVersion(query.getMonitorVersion())
                        .build())).orElse(ObjectiveMasterTargetDIO.builder().build());
                deptDIO.setObjMasterId(deptId);
                deptDIO.setObjMasterName(deptName);
                deptDIO.setObjMasterType(ObjectiveMasterTypeConst.MASTERTYPE_DEPT);
                return deptDIO;
            }).collect(Collectors.toList());
        }
        return Arrays.asList(this.getObjectiveMasterTargetDIOByRecord(query));
    }

    /**
     * 获取责任人指标数据
     * @param objectiveRecordQuery
     * @return
     */
    protected ObjectiveMasterTargetDIO getObjectiveMasterTargetDIOByRecord(ObjectiveRecordQuery objectiveRecordQuery){
        log.info("[{}]，获取监控数据，入参：{}，执行时间：{}" , TAG , JSON.toJSONString(objectiveRecordQuery) , DateUtil.getNowFormatted());
        //查询事件触发记录信息
        List<ObjectiveRecordCustomDIO> objectiveRecordCustomDIOList = Optional.ofNullable(objectiveRecordService.listObjectiveRecordByQuery(objectiveRecordQuery)).orElse(new ArrayList<>());
        if (objectiveRecordCustomDIOList.isEmpty()) {
            return null;
        }
        log.info("[{}]，获取监控数据，响应参数：{}，执行时间：{}" , TAG , JSON.toJSONString(objectiveRecordCustomDIOList) , DateUtil.getNowFormatted());
        ObjectiveRecordCustomDIO record = objectiveRecordCustomDIOList.get(0);
        //获取员工姓名
        String objMasterName = record.getObjMasterName();
        //获取当前责任人监控指标
        List<ObjectiveTargetDIO> targetDIOList = objectiveRecordCustomDIOList.stream().map(o -> {
            //查询监控记录日志
            String expand = o.getResult();
            //类型转换
            ObjectiveMonitorData data = JSONObject.parseObject(expand, ObjectiveMonitorData.class);
            //获取完成率
            BigDecimal objectiveRatioValueBigDecimal = BigDecimal.valueOf(Optional.ofNullable(data.getObjectiveRatioValue()).orElse(0.0));
            BigDecimal objectiveRatioValue = objectiveRatioValueBigDecimal.divide(BigDecimal.valueOf(100), 4,BigDecimal.ROUND_HALF_UP);
            return ObjectiveTargetDIO.builder()
                    .targetId(data.getObjCubeId())
                    .targetName(data.getObjName())
                    .objectiveValue(data.getCubeObjectiveValue())
                    .objectiveRatioValue(objectiveRatioValue.doubleValue())
                    .realValue(data.getCubeRealValue())
                    .warnLevel(data.getLevel())
                    .build();
        }).collect(Collectors.toList());
        //封装查询对象
        ObjectiveMasterTargetDIO masterTargetDIO = ObjectiveMasterTargetDIO.builder()
                .objMasterId(objectiveRecordQuery.getObjMasterId())
                .objMasterName(objMasterName)
                .objMasterType(ObjectiveMasterTypeConst.MASTERTYPE_PERSON)
                .targets(targetDIOList)
                .build();
        return masterTargetDIO;
    }

    /**
     * 获取数据层级
     * @param objMasterId
     * @param taskVerionId
     * @return
     */
    @Override
    public Integer getDataLevel(Integer objMasterId,String taskVerionId){
        //查询一级部门数据
        Integer level1 = Optional.ofNullable(objectiveRecordService.countByQuery(ObjectiveRecordQuery.builder()
                .parentDeptManagerId(objMasterId)
                .monitorVersion(taskVerionId)
                .build())).orElse(0);
        if(!NumberUtil.isNullOrZero(level1)){
            return ObjectiveMasterTypeConst.MASTERTYPE_DEFAULT;
        }
        //查询二级部门数据
        Integer level2 = Optional.ofNullable(objectiveRecordService.countByQuery(ObjectiveRecordQuery.builder()
                .deptManagerId(objMasterId)
                .monitorVersion(taskVerionId)
                .build())).orElse(0);
        if(!NumberUtil.isNullOrZero(level2)){
            return ObjectiveMasterTypeConst.MASTERTYPE_DEPT;
        }
        return ObjectiveMasterTypeConst.MASTERTYPE_PERSON;
    }
}
